package org.example.threaddemo;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * 线程池
 * https://blog.csdn.net/u013541140/article/details/95225769
 */
public class ThreadPoolMain {

    public static void main(String[] args) {
//        t1();
//        t2();
//        t3();
//        t4();
//        t5();
    }


    // 前三个任务先执行完,有空余线程执行第四个和第五个
    private static void t1() {
        System.out.println("main start");
        ExecutorService executorService = Executors.newFixedThreadPool(3);
        for (int i = 0; i < 5; i++) {
            final int finalI = i;
            executorService.execute(() -> {
                Thread thread = Thread.currentThread();
                System.out.println(thread.getId() + " start");
                for (int j = 0; j < 5; j++) {
                    long beginTime = System.currentTimeMillis();
                    while (System.currentTimeMillis() - beginTime < 1000) {
                    }
                    System.out.println(thread.getId() + " " + finalI + "-" + j);
                }
                System.out.println(thread.getId() + " end");
            });
        }
        executorService.shutdown();
        System.out.println("main end");
    }

    // 任务交替运行,CachedThreadPool会创建一个缓存区，将初始化的线程缓存起来，如果线程有可用的，就使用之前创建好的线程，如果没有可用的，就新创建线程，终止并且从缓存中移除已有60秒未被使用的线程。
    private static void t2() {
        System.out.println("main start");
        ExecutorService executorService = Executors.newCachedThreadPool();
        for (int i = 0; i < 5; i++) {
            final int finalI = i;
            executorService.execute(() -> {
                Thread thread = Thread.currentThread();
                System.out.println(thread.getId() + " start");
                for (int j = 0; j < 5; j++) {
                    long beginTime = System.currentTimeMillis();
                    while (System.currentTimeMillis() - beginTime < 1000) {
                    }
                    System.out.println(thread.getId() + " " + finalI + "-" + j);
                }
                System.out.println(thread.getId() + " end");
            });
        }
        executorService.shutdown();
        System.out.println("main end");
    }

    // 多个任务顺序执行,任务1完成后才会执行任务2
    private static void t3() {
        System.out.println("main start");
        ExecutorService executorService = Executors.newSingleThreadExecutor();
        for (int i = 0; i < 5; i++) {
            final int finalI = i;
            executorService.execute(() -> {
                Thread thread = Thread.currentThread();
                System.out.println(thread.getId() + " start");
                for (int j = 0; j < 5; j++) {
                    long beginTime = System.currentTimeMillis();
                    while (System.currentTimeMillis() - beginTime < 1000) {
                    }
                    System.out.println(thread.getId() + " " + finalI + "-" + j);
                }
                System.out.println(thread.getId() + " end");
            });
        }
        executorService.shutdown();
        System.out.println("main end");
    }

    // 执行时间比delay时间长,所以第四个任务和第五个任务,delay已经准备完,只要有空余线程就会立即start
    private static void t4() {
        System.out.println("main start");
        ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(3);

        for (int i = 0; i < 5; i++) {
            int finalI = i;
            scheduledExecutorService.scheduleAtFixedRate(() -> {
                Thread thread = Thread.currentThread();
                for (int j = 0; j < 5; j++) {
                    long beginTime = System.currentTimeMillis();
                    while (System.currentTimeMillis() - beginTime < 5 * 1000) {
                    }
                    System.out.println(thread.getId() + " " + finalI + "-" + j);
                }
            }, 1, 10, TimeUnit.SECONDS);
        }
        System.out.println("main end");
    }

    // 执行时间比delay时间长,所以第四个任务和第五个任务,先会执行,这时还有一个空余线程,就会计时其中一个任务,delay完后才会执行
    private static void t5() {
        System.out.println("main start");
        ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(3);

        for (int i = 0; i < 5; i++) {
            int finalI = i;
            scheduledExecutorService.scheduleWithFixedDelay(() -> {
                Thread thread = Thread.currentThread();
                for (int j = 0; j < 5; j++) {
                    long beginTime = System.currentTimeMillis();
                    while (System.currentTimeMillis() - beginTime < 5 * 1000) {
                    }
                    System.out.println(thread.getId() + " " + finalI + "-" + j);
                }
            }, 1, 10, TimeUnit.SECONDS);
        }
        System.out.println("main end");
    }
}
